package com.martin.dms.services.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.martin.dms.dataservices.SupplierDataService;
import com.martin.dms.factories.SupplierFactory;
import com.martin.dms.model.Item;
import com.martin.dms.model.Supplier;
import com.martin.dms.services.SupplierService;
import com.martin.dms.services.util.ServicesUtil;

/**
 * Implementation of the <code>SupplierService</code>.
 * 
 * @author mtsvetkov
 */
public class SupplierServiceImpl implements SupplierService {

    private SupplierDataService supplierDataService;
    private SupplierFactory supplierFactory;

    /**
     * Constructor.
     * 
     * @param supplierDataService - data service for the Supplier entity.
     * @param supplierFactory - factory service for the Supplier entity.
     */
    public SupplierServiceImpl(SupplierDataService supplierDataService, SupplierFactory supplierFactory) {
        this.supplierDataService = supplierDataService;
        this.supplierFactory = supplierFactory;
    }

    /**
     * {@inheritDoc}
     */
    public Supplier get(long id) {
        return supplierDataService.get(id);
    }

    /**
     * {@inheritDoc}
     */
    public void delete(long id) {
        supplierDataService.delete(id);
    }

    /**
     * {@inheritDoc}
     */
    public void create(String name, String email, String address, String phoneNumber, List<Long> itemIds) {
        Supplier supplier = supplierFactory.create(name, email, address, phoneNumber);
        supplier = supplierDataService.create(supplier);
        supplierDataService.addItems(supplier.getId(), itemIds);
    }

    /**
     * {@inheritDoc}
     */
    public void update(long id, String name, String email, String address, String phoneNumber, List<Long> itemIds) {
        supplierDataService.update(id, name, email, address, phoneNumber);
        supplierDataService.addItems(id, itemIds);
    }

    /**
     * {@inheritDoc}
     */
    public List<Supplier> findByNameEmailAndSuppliedItemName(String nameFilter, String emailFilter,
            String suppliedItemNameFilter) {
        List<Supplier> suppliers = supplierDataService.getAll();
        List<Supplier> result = new ArrayList<Supplier>();
        nameFilter = ServicesUtil.parseFilterString(nameFilter);
        emailFilter = ServicesUtil.parseFilterString(emailFilter);
        suppliedItemNameFilter = ServicesUtil.parseFilterString(suppliedItemNameFilter);

        boolean checkName = check(nameFilter);
        boolean checkEmail = check(emailFilter);
        boolean checkSuppliedItemName = check(suppliedItemNameFilter);

        for (Supplier supplier : suppliers) {
            if (checkName && !supplier.getName().toLowerCase().matches(nameFilter)) {
                continue;
            }
            if (checkEmail && !supplier.getEmail().toLowerCase().matches(emailFilter)) {
                continue;
            }
            if (checkSuppliedItemName && !suppliedItemNameMatches(supplier.getItems(), suppliedItemNameFilter)) {
                continue;
            }

            result.add(supplier);
        }
        return result;
    }

    private boolean check(String filter) {
        return !filter.equals(ServicesUtil.REGEX_STAR);
    }

    private boolean suppliedItemNameMatches(Set<Item> items, String suppliedItemNameFilter) {
        for (Item item : items) {
            if (item.getName().toLowerCase().matches(suppliedItemNameFilter)) {
                return true;
            }
        }
        return false;
    }

}
